home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / doom / quake2.zip / TF1_2SRC.ZIP / QUAKE / FORTRESS / SOURCE / WIZARD.QC < prev    next >
Text File  |  1996-08-17  |  11KB  |  411 lines

  1. /*
  2. ==============================================================================
  3.  
  4. WIZARD
  5.  
  6. ==============================================================================
  7. */
  8.  
  9. $cd /raid/quake/id1/models/a_wizard
  10. $origin 0 0 24
  11. $base wizbase    
  12. $skin wizbase
  13.  
  14. $frame hover1 hover2 hover3 hover4 hover5 hover6 hover7 hover8
  15. $frame hover9 hover10 hover11 hover12 hover13 hover14 hover15
  16.  
  17. $frame fly1 fly2 fly3 fly4 fly5 fly6 fly7 fly8 fly9 fly10
  18. $frame fly11 fly12 fly13 fly14
  19.  
  20. $frame magatt1 magatt2 magatt3 magatt4 magatt5 magatt6 magatt7
  21. $frame magatt8 magatt9 magatt10 magatt11 magatt12 magatt13
  22.  
  23. $frame pain1 pain2 pain3 pain4
  24.  
  25. $frame death1 death2 death3 death4 death5 death6 death7 death8
  26.  
  27. /*
  28. ==============================================================================
  29.  
  30. WIZARD
  31.  
  32. If the player moves behind cover before the missile is launched, launch it
  33. at the last visible spot with no velocity leading, in hopes that the player
  34. will duck back out and catch it.
  35. ==============================================================================
  36. */
  37.  
  38. /*
  39. =============
  40. LaunchMissile
  41.  
  42. Sets the given entities velocity and angles so that it will hit self.enemy
  43. if self.enemy maintains it's current velocity
  44. 0.1 is moderately accurate, 0.0 is totally accurate
  45. =============
  46. */
  47. void(entity missile, float mspeed, float accuracy) LaunchMissile =
  48. {
  49.     local    vector    vec, move;
  50.     local    float    fly;
  51.  
  52.     makevectors (self.angles);
  53.         
  54. // set missile speed
  55.     vec = self.enemy.origin + self.enemy.mins + self.enemy.size * 0.7 - missile.origin;
  56.  
  57. // calc aproximate time for missile to reach vec
  58.     fly = vlen (vec) / mspeed;
  59.     
  60. // get the entities xy velocity
  61.     move = self.enemy.velocity;
  62.     move_z = 0;
  63.  
  64. // project the target forward in time
  65.     vec = vec + move * fly;
  66.     
  67.     vec = normalize(vec);
  68.     vec = vec + accuracy*v_up*(random()- 0.5) + accuracy*v_right*(random()- 0.5);
  69.     
  70.     missile.velocity = vec * mspeed;
  71.  
  72.     missile.angles = '0 0 0';
  73.     missile.angles_y = vectoyaw(missile.velocity);
  74.  
  75. // set missile duration
  76.     missile.nextthink = time + 5;
  77.     missile.think = SUB_Remove;    
  78. };
  79.  
  80.  
  81. void() wiz_run1;
  82. void() wiz_side1;
  83.  
  84. /*
  85. =================
  86. WizardCheckAttack
  87. =================
  88. */
  89. float()    WizardCheckAttack =
  90. {
  91.     local vector    spot1, spot2;    
  92.     local entity    targ;
  93.     local float        chance;
  94.  
  95.     if (time < self.attack_finished)
  96.         return FALSE;
  97.     if (!enemy_vis)
  98.         return FALSE;
  99.  
  100.     if (enemy_range == RANGE_FAR)
  101.     {
  102.         if (self.attack_state != AS_STRAIGHT)
  103.         {
  104.             self.attack_state = AS_STRAIGHT;
  105.             wiz_run1 ();
  106.         }
  107.         return FALSE;
  108.     }
  109.         
  110.     targ = self.enemy;
  111.     
  112. // see if any entities are in the way of the shot
  113.     spot1 = self.origin + self.view_ofs;
  114.     spot2 = targ.origin + targ.view_ofs;
  115.  
  116.     traceline (spot1, spot2, FALSE, self);
  117.  
  118.     if (trace_ent != targ)
  119.     {    // don't have a clear shot, so move to a side
  120.         if (self.attack_state != AS_STRAIGHT)
  121.         {
  122.             self.attack_state = AS_STRAIGHT;
  123.             wiz_run1 ();
  124.         }
  125.         return FALSE;
  126.     }
  127.             
  128.     if (enemy_range == RANGE_MELEE)
  129.         chance = 0.9;
  130.     else if (enemy_range == RANGE_NEAR)
  131.         chance = 0.6;
  132.     else if (enemy_range == RANGE_MID)
  133.         chance = 0.2;
  134.     else
  135.         chance = 0;
  136.  
  137.     if (random () < chance)
  138.     {
  139.         self.attack_state = AS_MISSILE;
  140.         return TRUE;
  141.     }
  142.  
  143.     if (enemy_range == RANGE_MID)
  144.     {
  145.         if (self.attack_state != AS_STRAIGHT)
  146.         {
  147.             self.attack_state = AS_STRAIGHT;
  148.             wiz_run1 ();
  149.         }
  150.     }
  151.     else
  152.     {
  153.         if (self.attack_state != AS_SLIDING)
  154.         {
  155.             self.attack_state = AS_SLIDING;
  156.             wiz_side1 ();
  157.         }
  158.     }
  159.     
  160.     return FALSE;
  161. };
  162.  
  163. /*
  164. =================
  165. WizardAttackFinished
  166. =================
  167. */
  168. float()    WizardAttackFinished =
  169. {
  170.     if (enemy_range >= RANGE_MID || !enemy_vis)
  171.     {
  172.         self.attack_state = AS_STRAIGHT;
  173.         self.think = wiz_run1;
  174.     }
  175.     else
  176.     {
  177.         self.attack_state = AS_SLIDING;
  178.         self.think = wiz_side1;
  179.     }
  180. };
  181.  
  182. /*
  183. ==============================================================================
  184.  
  185. FAST ATTACKS
  186.  
  187. ==============================================================================
  188. */
  189.  
  190. void() Wiz_FastFire =
  191. {
  192.     local vector        vec;
  193.     local vector        dst;
  194.  
  195.     if (self.owner.health > 0)
  196.     {
  197.         self.owner.effects = self.owner.effects | EF_MUZZLEFLASH;
  198.  
  199.         makevectors (self.enemy.angles);    
  200.         dst = self.enemy.origin - 13*self.movedir;
  201.     
  202.         vec = normalize(dst - self.origin);
  203.         sound (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM);
  204.         launch_spike (self.origin, vec, 0, 0);
  205.         newmis.velocity = vec*600;
  206.         newmis.owner = self.owner;
  207.         newmis.classname = "wizspike";
  208.         setmodel (newmis, "progs/w_spike.mdl");
  209.         setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  210.     }
  211.  
  212.     remove (self);
  213. };
  214.  
  215.  
  216. void() Wiz_StartFast =
  217. {
  218.     local    entity    missile;
  219.     
  220.     sound (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM);
  221.     self.v_angle = self.angles;
  222.     makevectors (self.angles);
  223.  
  224.     missile = spawn ();
  225.     missile.owner = self;
  226.     missile.nextthink = time + 0.6;
  227.     setsize (missile, '0 0 0', '0 0 0');        
  228.     setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right*14);
  229.     missile.enemy = self.enemy;
  230.     missile.nextthink = time + 0.8;
  231.     missile.think = Wiz_FastFire;
  232.     missile.movedir = v_right;
  233.  
  234.     missile = spawn ();
  235.     missile.owner = self;
  236.     missile.nextthink = time + 1;
  237.     setsize (missile, '0 0 0', '0 0 0');        
  238.     setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right* -14);
  239.     missile.enemy = self.enemy;
  240.     missile.nextthink = time + 0.3;
  241.     missile.think = Wiz_FastFire;
  242.     missile.movedir = VEC_ORIGIN - v_right;
  243. };
  244.  
  245.  
  246.  
  247. void() Wiz_idlesound =
  248. {
  249. local float wr;
  250.     wr = random() * 5;
  251.  
  252.     if (self.waitmin < time)
  253.     {
  254.          self.waitmin = time + 2;
  255.          if (wr > 4.5) 
  256.              sound (self, CHAN_VOICE, "wizard/widle1.wav", 1,  ATTN_IDLE);
  257.          if (wr < 1.5)
  258.              sound (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE);
  259.     }
  260.     return;
  261. };
  262.  
  263. void()    wiz_stand1    =[    $hover1,        wiz_stand2    ] {ai_stand();};
  264. void()    wiz_stand2    =[    $hover2,        wiz_stand3    ] {ai_stand();};
  265. void()    wiz_stand3    =[    $hover3,        wiz_stand4    ] {ai_stand();};
  266. void()    wiz_stand4    =[    $hover4,        wiz_stand5    ] {ai_stand();};
  267. void()    wiz_stand5    =[    $hover5,        wiz_stand6    ] {ai_stand();};
  268. void()    wiz_stand6    =[    $hover6,        wiz_stand7    ] {ai_stand();};
  269. void()    wiz_stand7    =[    $hover7,        wiz_stand8    ] {ai_stand();};
  270. void()    wiz_stand8    =[    $hover8,        wiz_stand1    ] {ai_stand();};
  271.  
  272. void()    wiz_walk1    =[    $hover1,        wiz_walk2    ] {ai_walk(8);
  273. Wiz_idlesound();};
  274. void()    wiz_walk2    =[    $hover2,        wiz_walk3    ] {ai_walk(8);};
  275. void()    wiz_walk3    =[    $hover3,        wiz_walk4    ] {ai_walk(8);};
  276. void()    wiz_walk4    =[    $hover4,        wiz_walk5    ] {ai_walk(8);};
  277. void()    wiz_walk5    =[    $hover5,        wiz_walk6    ] {ai_walk(8);};
  278. void()    wiz_walk6    =[    $hover6,        wiz_walk7    ] {ai_walk(8);};
  279. void()    wiz_walk7    =[    $hover7,        wiz_walk8    ] {ai_walk(8);};
  280. void()    wiz_walk8    =[    $hover8,        wiz_walk1    ] {ai_walk(8);};
  281.  
  282. void()    wiz_side1    =[    $hover1,        wiz_side2    ] {ai_run(8);
  283. Wiz_idlesound();};
  284. void()    wiz_side2    =[    $hover2,        wiz_side3    ] {ai_run(8);};
  285. void()    wiz_side3    =[    $hover3,        wiz_side4    ] {ai_run(8);};
  286. void()    wiz_side4    =[    $hover4,        wiz_side5    ] {ai_run(8);};
  287. void()    wiz_side5    =[    $hover5,        wiz_side6    ] {ai_run(8);};
  288. void()    wiz_side6    =[    $hover6,        wiz_side7    ] {ai_run(8);};
  289. void()    wiz_side7    =[    $hover7,        wiz_side8    ] {ai_run(8);};
  290. void()    wiz_side8    =[    $hover8,        wiz_side1    ] {ai_run(8);};
  291.  
  292. void()    wiz_run1    =[    $fly1,        wiz_run2    ] {ai_run(16);
  293. Wiz_idlesound();
  294. };
  295. void()    wiz_run2    =[    $fly2,        wiz_run3    ] {ai_run(16);};
  296. void()    wiz_run3    =[    $fly3,        wiz_run4    ] {ai_run(16);};
  297. void()    wiz_run4    =[    $fly4,        wiz_run5    ] {ai_run(16);};
  298. void()    wiz_run5    =[    $fly5,        wiz_run6    ] {ai_run(16);};
  299. void()    wiz_run6    =[    $fly6,        wiz_run7    ] {ai_run(16);};
  300. void()    wiz_run7    =[    $fly7,        wiz_run8    ] {ai_run(16);};
  301. void()    wiz_run8    =[    $fly8,        wiz_run9    ] {ai_run(16);};
  302. void()    wiz_run9    =[    $fly9,        wiz_run10    ] {ai_run(16);};
  303. void()    wiz_run10    =[    $fly10,        wiz_run11    ] {ai_run(16);};
  304. void()    wiz_run11    =[    $fly11,        wiz_run12    ] {ai_run(16);};
  305. void()    wiz_run12    =[    $fly12,        wiz_run13    ] {ai_run(16);};
  306. void()    wiz_run13    =[    $fly13,        wiz_run14    ] {ai_run(16);};
  307. void()    wiz_run14    =[    $fly14,        wiz_run1    ] {ai_run(16);};
  308.  
  309. void()    wiz_fast1    =[    $magatt1,        wiz_fast2    ] {ai_face();Wiz_StartFast();};
  310. void()    wiz_fast2    =[    $magatt2,        wiz_fast3    ] {ai_face();};
  311. void()    wiz_fast3    =[    $magatt3,        wiz_fast4    ] {ai_face();};
  312. void()    wiz_fast4    =[    $magatt4,        wiz_fast5    ] {ai_face();};
  313. void()    wiz_fast5    =[    $magatt5,        wiz_fast6    ] {ai_face();};
  314. void()    wiz_fast6    =[    $magatt6,        wiz_fast7    ] {ai_face();};
  315. void()    wiz_fast7    =[    $magatt5,        wiz_fast8    ] {ai_face();};
  316. void()    wiz_fast8    =[    $magatt4,        wiz_fast9    ] {ai_face();};
  317. void()    wiz_fast9    =[    $magatt3,        wiz_fast10    ] {ai_face();};
  318. void()    wiz_fast10    =[    $magatt2,        wiz_run1    ] {ai_face();SUB_AttackFinished(2);WizardAttackFinished ();};
  319.  
  320. void()    wiz_pain1    =[    $pain1,        wiz_pain2    ] {};
  321. void()    wiz_pain2    =[    $pain2,        wiz_pain3    ] {};
  322. void()    wiz_pain3    =[    $pain3,        wiz_pain4    ] {};
  323. void()    wiz_pain4    =[    $pain4,        wiz_run1    ] {};
  324.  
  325. void()    wiz_death1    =[    $death1,        wiz_death2    ] {
  326.  
  327. self.velocity_x = -200 + 400*random();
  328. self.velocity_y = -200 + 400*random();
  329. self.velocity_z = 100 + 100*random();
  330. self.flags = self.flags - (self.flags & FL_ONGROUND);
  331. sound (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM);
  332. };
  333. void()    wiz_death2    =[    $death2,        wiz_death3    ] {};
  334. void()    wiz_death3    =[    $death3,        wiz_death4    ]{self.solid = SOLID_NOT;};
  335. void()    wiz_death4    =[    $death4,        wiz_death5    ] {};
  336. void()    wiz_death5    =[    $death5,        wiz_death6    ] {};
  337. void()    wiz_death6    =[    $death6,        wiz_death7    ] {};
  338. void()    wiz_death7    =[    $death7,        wiz_death8    ] {};
  339. void()    wiz_death8    =[    $death8,        wiz_death8    ] {};
  340.  
  341. void() wiz_die =
  342. {
  343. // check for gib
  344.     if (self.health < -40)
  345.     {
  346.         sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
  347.         ThrowHead ("progs/h_wizard.mdl", self.health);
  348.         ThrowGib ("progs/gib2.mdl", self.health);
  349.         ThrowGib ("progs/gib2.mdl", self.health);
  350.         ThrowGib ("progs/gib2.mdl", self.health);
  351.         return;
  352.     }
  353.  
  354.     wiz_death1 ();
  355. };
  356.  
  357.  
  358. void(entity attacker, float damage) Wiz_Pain =
  359. {
  360.     sound (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM);
  361.     if (random()*70 > damage)
  362.         return;        // didn't flinch
  363.  
  364.     wiz_pain1 ();
  365. };
  366.  
  367.  
  368. void() Wiz_Missile =
  369. {
  370.     wiz_fast1();
  371. };
  372.  
  373. /*QUAKED monster_wizard (1 0 0) (-16 -16 -24) (16 16 40) Ambush
  374. */
  375. void() monster_wizard =
  376. {
  377.     if (deathmatch)
  378.     {
  379.         remove(self);
  380.         return;
  381.     }
  382.     precache_model ("progs/wizard.mdl");
  383.     precache_model ("progs/h_wizard.mdl");
  384.     precache_model ("progs/w_spike.mdl");
  385.  
  386.     precache_sound ("wizard/hit.wav");        // used by c code
  387.     precache_sound ("wizard/wattack.wav");
  388.     precache_sound ("wizard/wdeath.wav");
  389.     precache_sound ("wizard/widle1.wav");
  390.     precache_sound ("wizard/widle2.wav");
  391.     precache_sound ("wizard/wpain.wav");
  392.     precache_sound ("wizard/wsight.wav");
  393.  
  394.     self.solid = SOLID_SLIDEBOX;
  395.     self.movetype = MOVETYPE_STEP;
  396.  
  397.     setmodel (self, "progs/wizard.mdl");
  398.  
  399.     setsize (self, '-16 -16 -24', '16 16 40');
  400.     self.health = 80;
  401.  
  402.     self.th_stand = wiz_stand1;
  403.     self.th_walk = wiz_walk1;
  404.     self.th_run = wiz_run1;
  405.     self.th_missile = Wiz_Missile;
  406.     self.th_pain = Wiz_Pain;
  407.     self.th_die = wiz_die;
  408.         
  409.     flymonster_start ();
  410. };
  411.